﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.IsoParametricCurves.IsoParametricCurveCreator
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using EngineeringInternalExtension.Options;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Resources;
using System.Windows.Forms;
using Tecnomatix.Engineering;
using Tecnomatix.Engineering.DataTypes;


namespace DnProcessSimulateCommands.IsoParametricCurves;

public class IsoParametricCurveCreator
{
  private TxObjectList<ITx1Dimensional> m_leadingCurves;
  private IsoParemtricCurveData m_IsoParemtricCurveData;
  private TxObjectList<ITx1Dimensional> m_isoParametricCurves;
  private TxSolid m_arrowHead;
  private ITx1Dimensional m_arrowLine;
  private ITx1Dimensional m_visibleLeadingCurve;
  private int m_curveNum;
  private TxColor m_leadingCurveColor;
  private TxColor m_isoParametricCurvesColor;
  private TxColor m_manipulatorColor;
  private const double safeDistanceFromEndPoint = 0.01;

  public IsoParametricCurveCreator(IsoParemtricCurveData data)
  {
    this.m_leadingCurves = new TxObjectList<ITx1Dimensional>();
    this.m_isoParametricCurves = new TxObjectList<ITx1Dimensional>();
    this.m_IsoParemtricCurveData = data;
    this.m_leadingCurveColor = TxColor.TxColorRed;
    this.m_isoParametricCurvesColor = TxColor.TxColorBlue;
    this.m_manipulatorColor = TxColor.TxColorOrange;
  }

  ~IsoParametricCurveCreator()
  {
  }

  public virtual void Dispose()
  {
  }

  public int ChangeDirection() => 0;

  public void CreateCurves(bool isPersist)
  {
    if (this.m_leadingCurves == null || ((IEnumerable<ITx1Dimensional>) this.m_leadingCurves).Count<ITx1Dimensional>() < 1 || this.m_IsoParemtricCurveData.NumberOfCurves > this.m_IsoParemtricCurveData.MaxNumberCurves)
      return;
    this.m_curveNum = 1;
    ITx1Dimensional leadingCurve = ((Collection<ITx1Dimensional>) this.m_leadingCurves)[0];
    TxVector startPoint = leadingCurve.StartPoint;
    List<int> failedCurves = new List<int>();
    TxVector lengthAlongTheCurve = leadingCurve.GetPointByLengthAlongTheCurve(startPoint, this.m_IsoParemtricCurveData.DistanceFromStartingPoint);
    this.CreatOneCurveAndAcuumalteProblematics(lengthAlongTheCurve, isPersist, failedCurves);
    for (int index = 2; index <= this.m_IsoParemtricCurveData.NumberOfCurves; ++index)
    {
      lengthAlongTheCurve = leadingCurve.GetPointByLengthAlongTheCurve(lengthAlongTheCurve, this.m_IsoParemtricCurveData.DistanceBetweenCurves);
      this.CreatOneCurveAndAcuumalteProblematics(lengthAlongTheCurve, isPersist, failedCurves);
    }
    if (failedCurves.Count <= 0)
      return;
    this.PopErrorMessage(failedCurves);
  }

  private void CreatOneCurveAndAcuumalteProblematics(
    TxVector point,
    bool isPersist,
    List<int> failedCurves)
  {
    try
    {
      this.createIsoLine(point, isPersist);
    }
    catch
    {
      if (!isPersist)
        return;
      failedCurves.Add(this.m_curveNum);
      ++this.m_curveNum;
    }
  }

  private void PopErrorMessage(List<int> failedCurves)
  {
    ResourceManager resourceManager = new ResourceManager("DnProcessSimulateCommands.StringTable", this.GetType().Assembly);
    string str1 = resourceManager.GetString("ISOPARAMETRIC_CURVES_NAME");
    string str2 = resourceManager.GetString("ISOPARAMETRIC_CURVES_FAILED_CURVES_ERROR");
    for (int index = 0; index < failedCurves.Count; ++index)
    {
      str2 = $"{str2} {failedCurves.ElementAt<int>(index).ToString()}";
      if (index != failedCurves.Count - 1)
        str2 += ",";
    }
    int num = (int) TxMessageBox.Show(str2 + ".", str1, MessageBoxButtons.OK, MessageBoxIcon.Hand);
  }

  private void createIsoLine(TxVector location, bool isPersist)
  {
    TxUVParametersPoint pointProjection = this.m_IsoParemtricCurveData.Face.GetPointProjection(location);
    TxColor color = isPersist ? TxColor.FromBgrColor(TxApplication.Options.Color.SolidColor) : this.m_isoParametricCurvesColor;
    TxObjectList<ITx1Dimensional> txObjectList = !this.m_IsoParemtricCurveData.isInUdirection() ? this.CreateCurves(isPersist, true, ((TxUVParametersPoint) ref pointProjection).V, color) : this.CreateCurves(isPersist, false, ((TxUVParametersPoint) ref pointProjection).U, color);
    if (isPersist)
      return;
    this.m_isoParametricCurves.AddRange(txObjectList);
  }

  private double calculateParametricValue(TxVector nextPoint)
  {
    TxUVParametersPoint pointProjection = this.m_IsoParemtricCurveData.Face.GetPointProjection(nextPoint);
    return this.m_IsoParemtricCurveData.isInUdirection() ? ((TxUVParametersPoint) ref pointProjection).V : ((TxUVParametersPoint) ref pointProjection).U;
  }

  public void CreateLeadingCurves()
  {
    TxUVParametersRectangle faceRectangle = this.m_IsoParemtricCurveData.FaceRectangle;
    bool isInUdirection = this.m_IsoParemtricCurveData.isInUdirection();
    double num1;
    double num2;
    if (isInUdirection)
    {
      TxUVParametersPoint uvParametersPoint = ((TxUVParametersRectangle) ref faceRectangle).MinimumUV;
      num1 = ((TxUVParametersPoint) ref uvParametersPoint).V;
      uvParametersPoint = ((TxUVParametersRectangle) ref faceRectangle).MaximumUV;
      num2 = ((TxUVParametersPoint) ref uvParametersPoint).V;
    }
    else
    {
      TxUVParametersPoint uvParametersPoint = ((TxUVParametersRectangle) ref faceRectangle).MinimumUV;
      num1 = ((TxUVParametersPoint) ref uvParametersPoint).U;
      uvParametersPoint = ((TxUVParametersRectangle) ref faceRectangle).MaximumUV;
      num2 = ((TxUVParametersPoint) ref uvParametersPoint).U;
    }
    double startingPoint = (num2 + num1) / 2.0;
    this.m_leadingCurves = this.CreateCurves(false, isInUdirection, startingPoint, this.m_leadingCurveColor);
    if (this.m_IsoParemtricCurveData.isInNegativeDirection())
      this.ChangeDirectionOfLeadingCurves();
    this.DeleteUnecessaryLeadingCurves();
    this.setLeadingCurveLength();
  }

  private void ChangeDirectionOfLeadingCurves()
  {
    TxObjectList<ITx1Dimensional> curves = new TxObjectList<ITx1Dimensional>();
    for (int index = ((IEnumerable<ITx1Dimensional>) this.m_leadingCurves).Count<ITx1Dimensional>() - 1; index >= 0; --index)
    {
      ITx1Dimensional leadingCurve = ((Collection<ITx1Dimensional>) this.m_leadingCurves)[index];
      TxCurveReverseCreationData reverseCreationData = new TxCurveReverseCreationData(leadingCurve);
      reverseCreationData.SetAsDisplay();
      ITxGeometryCreation scope = this.m_IsoParemtricCurveData.Scope;
      ((Collection<ITx1Dimensional>) curves).Add(scope.CreateCurveByReversing(reverseCreationData));
      ((ITxObject) leadingCurve).Delete();
    }
    this.m_leadingCurves = curves;
    this.ColorCurve(curves, this.m_leadingCurveColor);
  }

  private TxObjectList<ITx1Dimensional> CreateCurves(
    bool isPersist,
    bool isInUdirection,
    double startingPoint,
    TxColor color)
  {
    TxCurveIsoParametricCreationData parametricCreationData = new TxCurveIsoParametricCreationData(this.m_IsoParemtricCurveData.Face, startingPoint);
    if (!isPersist)
      parametricCreationData.SetAsDisplay();
    ITxGeometryCreation scope = this.m_IsoParemtricCurveData.Scope;
    TxObjectList<ITx1Dimensional> txObjectList = !isInUdirection ? scope.CreateIsoParametricCurveInVDirection(parametricCreationData) : scope.CreateIsoParametricCurveInUDirection(parametricCreationData);
    TxObjectList<ITx1Dimensional> curves = new TxObjectList<ITx1Dimensional>();
    foreach (ITx1Dimensional itx1Dimensional in (Collection<ITx1Dimensional>) txObjectList)
    {
      if (isPersist)
      {
        if (TxGroup.op_Inequality(this.m_IsoParemtricCurveData.Block, (ITxObject) null))
          ((ITxObject) itx1Dimensional).Name = $"{this.m_IsoParemtricCurveData.Block.Name}_curve_{this.m_curveNum.ToString()}";
        else
          ((ITxObject) itx1Dimensional).Name = "set_curve_" + this.m_curveNum.ToString();
        ++this.m_curveNum;
      }
      ((Collection<ITx1Dimensional>) curves).Add(itx1Dimensional);
      if (isPersist && TxGroup.op_Inequality(this.m_IsoParemtricCurveData.Block, (ITxObject) null))
        this.m_IsoParemtricCurveData.Block.AddObject((ITxObject) itx1Dimensional);
    }
    this.ColorCurve(curves, color);
    return curves;
  }

  private void ColorCurve(TxObjectList<ITx1Dimensional> curves, TxColor color)
  {
    foreach (ITx1Dimensional curve in (Collection<ITx1Dimensional>) curves)
    {
      if (curve is ITxDisplayableObject displayableObject && TxColor.op_Inequality(color, (TxColor) null))
        displayableObject.Color = color;
    }
  }

  private void ColorCurve(ITx1Dimensional curve, TxColor color)
  {
    if (!(curve is ITxDisplayableObject displayableObject) || !TxColor.op_Inequality(color, (TxColor) null))
      return;
    displayableObject.Color = color;
  }

  private void DeleteCurves(TxObjectList<ITx1Dimensional> curve)
  {
    if (curve == null)
      return;
    for (int index = 0; index < ((Collection<ITx1Dimensional>) curve).Count; ++index)
      ((ITxObject) ((Collection<ITx1Dimensional>) curve)[index]).Delete();
  }

  private void CreateManipulator()
  {
    double arrowLength = this.getArrowLength();
    double arrowLineLength = arrowLength / 1.5;
    ITx1Dimensional leadingCurve = ((Collection<ITx1Dimensional>) this.m_leadingCurves)[0];
    ITxGeometryCreation scope = this.m_IsoParemtricCurveData.Scope;
    TxCurveTrimmingCreationData trimmingCreationData1 = new TxCurveTrimmingCreationData(leadingCurve, 0.0, leadingCurve.Length() - arrowLineLength);
    trimmingCreationData1.SetAsDisplay();
    this.m_arrowLine = scope.CreateCurveByTrimming(trimmingCreationData1);
    this.ColorCurve(this.m_arrowLine, this.m_manipulatorColor);
    TxCurveTrimmingCreationData trimmingCreationData2 = new TxCurveTrimmingCreationData(leadingCurve, arrowLength, 0.0);
    trimmingCreationData2.SetAsDisplay();
    this.m_visibleLeadingCurve = scope.CreateCurveByTrimming(trimmingCreationData2);
    this.ColorCurve(this.m_visibleLeadingCurve, this.m_leadingCurveColor);
    (leadingCurve as ITxDisplayableObject).Blank();
    double arrowHeadLength = this.GetArrowHeadLength(this.m_arrowLine.EndPoint, arrowLineLength);
    TxVector endPoint = this.m_arrowLine.EndPoint;
    TxConeCreationData coneCreationData = new TxConeCreationData("arrowTip", leadingCurve.GetPointByLengthAlongTheCurve(endPoint, arrowHeadLength), endPoint, 0.0, arrowHeadLength / 3.0);
    coneCreationData.SetAsDisplay();
    this.m_arrowHead = scope.CreateSolidCone(coneCreationData);
    this.m_arrowHead.Color = this.m_manipulatorColor;
  }

  private double GetArrowHeadLength(TxVector point, double arrowLineLength)
  {
    double val1 = arrowLineLength / 2.0;
    TxUVParametersPoint pointProjection = this.m_IsoParemtricCurveData.Face.GetPointProjection(point);
    TxObjectList<ITx1Dimensional> curve = !this.m_IsoParemtricCurveData.isInUdirection() ? this.CreateCurves(false, true, ((TxUVParametersPoint) ref pointProjection).V, TxColor.TxColorWhite) : this.CreateCurves(false, false, ((TxUVParametersPoint) ref pointProjection).U, TxColor.TxColorWhite);
    double num = ((Collection<ITx1Dimensional>) curve)[0].Length();
    this.DeleteCurves(curve);
    return Math.Min(val1, num / 3.0);
  }

  private double getArrowLength()
  {
    double arrowLength = 225.0;
    ITx1Dimensional leadingCurve = ((Collection<ITx1Dimensional>) this.m_leadingCurves)[0];
    if (arrowLength >= leadingCurve.Length())
      arrowLength = leadingCurve.Length() / 3.0;
    return arrowLength;
  }

  public void Persist(bool clearPreview)
  {
    TxApplication.ActiveUndoManager.StartTransaction();
    this.CreateBlock();
    this.CreateCurves(true);
    this.ClearPreview(clearPreview, clearPreview);
    TxApplication.RefreshDisplay();
    TxApplication.ActiveUndoManager.EndTransaction();
  }

  public void Preview(bool previewLeadingCurve, bool previewIsoParametricCurves)
  {
    this.ClearPreview(previewIsoParametricCurves, previewLeadingCurve);
    if (this.m_IsoParemtricCurveData.Face != null)
    {
      if (previewLeadingCurve)
      {
        this.CreateLeadingCurves();
        this.CreateManipulator();
      }
      this.SetMaxNumberOfCurves();
      if (previewIsoParametricCurves)
        this.CreateCurves(false);
    }
    TxApplication.RefreshDisplay();
  }

  public void ClearPreview(bool clearCurves, bool clearLeadingCurveAndManipulator)
  {
    if (clearLeadingCurveAndManipulator)
    {
      this.DeleteCurves(this.m_leadingCurves);
      if (this.m_leadingCurves != null)
        ((Collection<ITx1Dimensional>) this.m_leadingCurves).Clear();
      this.DeleteManipulator();
    }
    if (clearCurves)
    {
      this.DeleteCurves(this.m_isoParametricCurves);
      if (this.m_isoParametricCurves != null)
        ((Collection<ITx1Dimensional>) this.m_isoParametricCurves).Clear();
    }
    TxApplication.RefreshDisplay();
  }

  private void CreateBlock()
  {
    TxComponent scope = this.m_IsoParemtricCurveData.Scope as TxComponent;
    int digitsAfterDecPoint = TxOptionsEx.LinearDigitsAfterDecPoint;
    TxGroupCreationData groupCreationData = new TxGroupCreationData(this.CreateUniqueBlockName($"{this.m_IsoParemtricCurveData.NamePrefix}_{this.m_IsoParemtricCurveData.DistanceFromStartingPointByUnitStr}_{this.m_IsoParemtricCurveData.DistanceBetweenCurvesByUnitStr}_{this.m_IsoParemtricCurveData.NumberOfCurves.ToString()}"));
    this.m_IsoParemtricCurveData.Block = ((TxBaseGeometryCreationObject) scope).CreateGroup(groupCreationData);
    this.m_IsoParemtricCurveData.Block.Detach();
  }

  private string CreateUniqueBlockName(string name)
  {
    TxObjectList directDescendants = (this.m_IsoParemtricCurveData.Scope as TxComponent).GetDirectDescendants((ITxTypeFilter) new TxTypeFilter(typeof (TxGroup)));
    if (directDescendants == null)
      return "";
    if (!this.DoesObjectExistInList(name, directDescendants))
      return name;
    int num = 1;
    while (this.DoesObjectExistInList($"{name}_{num.ToString()}", directDescendants))
      ++num;
    return $"{name}_{num.ToString()}";
  }

  private bool DoesObjectExistInList(string name, TxObjectList list)
  {
    foreach (ITxObject itxObject in (Collection<ITxObject>) list)
    {
      if (itxObject.Name == name)
        return true;
    }
    return false;
  }

  private void DeleteLeadingCurveAndManipulator()
  {
    this.DeleteCurves(this.m_leadingCurves);
    ((Collection<ITx1Dimensional>) this.m_leadingCurves).Clear();
    this.DeleteManipulator();
  }

  private void DeleteManipulator()
  {
    if (TxSolid.op_Inequality(this.m_arrowHead, (ITxObject) null))
    {
      this.m_arrowHead.Delete();
      this.m_arrowHead = (TxSolid) null;
    }
    if (this.m_arrowLine != null)
    {
      ((ITxObject) this.m_arrowLine).Delete();
      this.m_arrowLine = (ITx1Dimensional) null;
    }
    if (this.m_visibleLeadingCurve == null)
      return;
    ((ITxObject) this.m_visibleLeadingCurve).Delete();
    this.m_visibleLeadingCurve = (ITx1Dimensional) null;
  }

  public void IsoParemtricCurveCreator(IsoParemtricCurveData data)
  {
  }

  public void setLeadingCurveLength()
  {
    TxObjectList<ITx1Dimensional> leadingCurves = this.m_leadingCurves;
    double num = 0.0;
    if (leadingCurves != null && ((IEnumerable<ITx1Dimensional>) leadingCurves).Count<ITx1Dimensional>() > 0)
      num = ((Collection<ITx1Dimensional>) leadingCurves)[0].Length();
    this.m_IsoParemtricCurveData.LeadingCurveLength = num;
  }

  public void SetMaxNumberOfCurves()
  {
    double distanceBetweenCurves = this.m_IsoParemtricCurveData.DistanceBetweenCurves;
    if (distanceBetweenCurves == 0.0)
      this.m_IsoParemtricCurveData.MaxNumberCurves = 1;
    else
      this.m_IsoParemtricCurveData.MaxNumberCurves = (int) ((this.m_IsoParemtricCurveData.LeadingCurveLength - this.m_IsoParemtricCurveData.DistanceFromStartingPoint - 0.01) / distanceBetweenCurves) + 1;
  }

  private void DeleteUnecessaryLeadingCurves()
  {
    int count = ((Collection<ITx1Dimensional>) this.m_leadingCurves).Count;
    ITx1Dimensional leadingCurve1 = ((Collection<ITx1Dimensional>) this.m_leadingCurves)[0];
    if (count <= 1)
      return;
    for (int index = 1; index < count; ++index)
    {
      ITx1Dimensional leadingCurve2 = ((Collection<ITx1Dimensional>) this.m_leadingCurves)[index];
      if (((ITxObject) leadingCurve2).CanBeDeleted)
        ((ITxObject) leadingCurve2).Delete();
    }
    ((Collection<ITx1Dimensional>) this.m_leadingCurves).Clear();
    ((Collection<ITx1Dimensional>) this.m_leadingCurves).Add(leadingCurve1);
  }
}
